package org.jsola.hr.common.wechat;

import com.alibaba.fastjson.JSONObject;
import kong.unirest.HttpResponse;
import kong.unirest.Unirest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringEscapeUtils;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.jsola.hr.constant.ConfigCodeConstants;
import org.jsola.hr.provider.ISiteConfigProviderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 消息处理工具类
 * Created by
 */
@Slf4j
@Component("hrMessageHandlerUtil")
public class MessageHandlerUtil {

    @Autowired
    ISiteConfigProviderService siteConfigProviderService;

    /**
     * 解析微信发来的请求（XML）
     *
     * @param request
     * @return map
     * @throws Exception
     */
    public static Map<String, String> parseXml(HttpServletRequest request) throws Exception {
        // 将解析结果存储在HashMap中
        Map<String, String> map = new HashMap(16);
        // 从request中取得输入流
        InputStream inputStream = request.getInputStream();

        InputStreamReader inputReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
        BufferedReader buffer = new BufferedReader(inputReader);
        StringBuilder message = new StringBuilder();
        String s = "";
        while ((s = buffer.readLine()) != null) {
            message.append(s);
        }
        System.out.println(message);
        System.out.println("获取输入流");
        String messageStr = StringEscapeUtils.unescapeXml(message.toString());
        Document document = DocumentHelper.parseText(messageStr);

        // 读取输入流
        // SAXReader reader = new SAXReader();
        // Document document = reader.read(inputStream);
        // 得到xml根元素
        Element root = document.getRootElement();
        // 得到根元素的所有子节点
        List<Element> elementList = root.elements();

        // 遍历所有子节点
        for (Element e : elementList) {
            map.put(e.getName(), e.getText());
        }

        // 释放资源
        inputStream.close();
        inputStream = null;
        return map;
    }

    public static AccessToken getAccessToken(String appId, String appSecret) {
        Map<String, String> params = new HashMap<>();
        params.put("grant_type", "client_credential");
        params.put("appid", appId);
        params.put("secret", appSecret);
        String url = "https://api.weixin.qq.com/cgi-bin/token";
        /**
         * 接口地址为https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET，其中grant_type固定写为client_credential即可。
         */
        //此请求为https的get请求，返回的数据格式为{"access_token":"ACCESS_TOKEN","expires_in":7200}
        Map<String, Object> result = HttpUtils.httpGet(url, params);
        log.info("获取到的access_token=" + result);
        AccessToken token = new AccessToken();
        token.setAccessToken(result.get("access_token").toString());
        token.setExpiresin(Integer.parseInt(result.get("expires_in").toString()));
        return token;
    }

    /**
     * 根据用户的openid获取用户信息
     *
     * @param openid   openid
     * @param tenantId 租户id
     * @return 用户信息
     */
    public Map<String, Object> getUserInfo(String openid, String tenantId) {
        String url = "https://api.weixin.qq.com/cgi-bin/user/info";
        Map<String, String> parameters = new HashMap<>(16);
        // 公众号appid ,appSecret
        String appid = siteConfigProviderService.selectValueByCode(ConfigCodeConstants.CODE_APPID, tenantId);
        String secret = siteConfigProviderService.selectValueByCode(ConfigCodeConstants.CODE_SECRET, tenantId);
        log.info("appid:{},secret:{}", appid, secret);
        parameters.put("access_token", getAccessToken(appid, secret).getAccessToken());
        parameters.put("openid", openid);
        Map<String, Object> resultMap = HttpUtils.httpGet(url, parameters);
        log.info("根据用户的openid获取用户信息,resultMap:{}", resultMap);
        return resultMap;
    }

    /**
     * 根据用户的openid获取用户信息
     *
     * @param openid openid
     * @param appid  appid
     * @param secret 秘钥
     * @return 用户信息
     */
    public Map<String, Object> getUserInfo(String openid, String appid, String secret) {
        String url = "https://api.weixin.qq.com/cgi-bin/user/info";
        Map<String, String> parameters = new HashMap<>(16);
        log.info("appid:{},secret:{}", appid, secret);
        parameters.put("access_token", getAccessToken(appid, secret).getAccessToken());
        parameters.put("openid", openid);
        Map<String, Object> resultMap = HttpUtils.httpGet(url, parameters);
        log.info("根据用户的openid获取用户信息,resultMap:{}", resultMap);
        return resultMap;
    }


    /**
     * 获取OpenLink
     */
    public static String getOpenLink(String accessToken, JumpWxa jumpWxa) {
        SchemeQuery schemeQuery = new SchemeQuery();
        schemeQuery.setJumpWxa(jumpWxa);
        HttpResponse<OpenLink> openLinkResponse = Unirest.post("https://api.weixin.qq.com/wxa/generatescheme")
                //.queryString("jump_wxa",JSONObject.toJSONString(jumpWxa))
                .body(JSONObject.toJSONString(schemeQuery))
                .queryString("access_token", accessToken)
                .queryString("expire_type",1)
                .queryString("expire_interval",30)
                .asObject(OpenLink.class);
        return openLinkResponse.getBody().getOpenlink();
    }
}